package cn.lg.soar.system.auth.service.impl;

import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.current.IBaseUser;
import cn.lg.soar.system.auth.entity.TemporaryPassword;
import cn.lg.soar.system.auth.mapper.TemporaryPasswordMapper;
import cn.lg.soar.system.auth.model.TemporaryPasswordVo;
import cn.lg.soar.system.auth.service.ITemporaryPasswordService;
import cn.lg.soar.system.util.PasswordUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * TemporaryPassword服务层实现
 * 租户
 * @author luguoxiang
 * @since 2022-04-30
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class TemporaryPasswordServiceImpl extends ServiceImpl<TemporaryPasswordMapper, TemporaryPassword> implements ITemporaryPasswordService {

    @Override
    public Long create(IBaseUser user, TemporaryPasswordVo vo) {
        TemporaryPassword entity = vo.toTemporaryPassword();
        entity.setUserId(user.getId());
        entity.setSalt(IdWorker.get32UUID());
        entity.setPassword(
                PasswordUtils.encrypt(entity.getPassword(), entity.getSalt(), user.getUsername())
        );
        AssertUtil.isTrue(save(entity), "创建失败");
        return entity.getId();
    }

    @Override
    public void update(IBaseUser user, TemporaryPasswordVo vo) {
        TemporaryPassword entity = vo.toTemporaryPassword();
        if (entity.getPassword() != null) {
            entity.setSalt(IdWorker.get32UUID());
            entity.setPassword(
                    PasswordUtils.encrypt(entity.getPassword(), entity.getSalt(), user.getUsername())
            );
        }
        AssertUtil.isTrue(updateById(entity), "修改失败");
    }

    @Override
    public boolean verifyPassword(Long userId, String username, String password) {
        // 使用临时密码登录
        TemporaryPassword tp = getByUserId(userId);
        if (tp == null) {
            return false;
        }
        if (!PasswordUtils.verify(password, tp.getSalt(), username, tp.getPassword())) {
            return false;
        }
        // 验证临时密码的有效性
        if (!Objects.equals(tp.getMaxCount(), 0)) {
            AssertUtil.isTrue(tp.getMaxCount() > tp.getUsageCount(), "临时密码次数已用完");
        }
        if (tp.getExpires() != null) {
            AssertUtil.isTrue(LocalDateTime.now().isBefore(tp.getExpires()), "临时密码已过期");
        }
        // 记录使用次数
        loginCount(tp);
        return true;
    }
}
